package com.ruoyi.system.service.aggregation.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.utils.RedisLockUtil;
import com.ruoyi.system.domain.aggregation.Account;
import com.ruoyi.system.domain.aggregation.Order;
import com.ruoyi.system.domain.aggregation.Point;
import com.ruoyi.system.domain.aggregation.Product;
import com.ruoyi.system.mapper.aggregation.AccountMapper;
import com.ruoyi.system.mapper.aggregation.OrderMapper;
import com.ruoyi.system.mapper.aggregation.PointMapper;
import com.ruoyi.system.mapper.aggregation.ProductMapper;
import com.ruoyi.system.service.aggregation.ICommissionService;
import com.ruoyi.system.service.aggregation.IOrderService;
import com.ruoyi.system.service.aggregation.IProductStockService;

/**
 * 订单Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-01-01
 */
@Service
public class OrderServiceImpl implements IOrderService 
{
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private PointMapper pointMapper;

    @Autowired
    private ICommissionService commissionService;

    @Autowired
    private IProductStockService productStockService;

    @Autowired
    private RedisLockUtil redisLockUtil;

    @Override
    public Order selectOrderById(Long id)
    {
        return orderMapper.selectOrderById(id);
    }

    @Override
    public List<Order> selectOrderList(Order order)
    {
        return orderMapper.selectOrderList(order);
    }

    /**
     * 创建订单
     */
    @Override
    @Transactional
    public Order createOrder(Order order)
    {
        // 查询商品信息
        Product product = productMapper.selectProductById(order.getProductId());
        if (product == null)
        {
            throw new ServiceException("商品不存在");
        }

        // 检查库存
        if (product.getNum() < order.getNum())
        {
            throw new ServiceException("库存不足");
        }

        // 计算订单金额
        Long totalAmount = product.getPrice() * order.getNum();
        order.setPrice(product.getPrice());
        order.setAmount(totalAmount);
        order.setMerchantId(product.getMerchantId());
        order.setAttribute(product.getAttribute());
        order.setStatue(1); // 待支付
        order.setDeleted(0);
        order.setCreateTime(new Date());
        
        // 生成订单ID（雪花算法或时间戳）
        order.setId(System.currentTimeMillis());

        orderMapper.insertOrder(order);
        return order;
    }

    /**
     * 支付订单（积分+人民币混合支付）
     * 100积分 = 1元
     * 优化：使用分布式锁防止重复支付，使用Redis库存缓存防止超卖
     */
    @Override
    @Transactional
    public void payOrder(Long orderId, Long payAmount, Long payPointAmount)
    {
        // 使用分布式锁防止重复支付
        String lockKey = "order:pay:" + orderId;
        String lockValue = null;
        
        try {
            lockValue = redisLockUtil.tryLock(lockKey, 10);
            if (lockValue == null) {
                throw new ServiceException("订单正在处理中，请勿重复提交");
            }
            
            Order order = orderMapper.selectOrderById(orderId);
            if (order == null)
            {
                throw new ServiceException("订单不存在");
            }

            if (order.getStatue() != 1)
            {
                throw new ServiceException("订单状态不正确");
            }

            // 获取C端用户账户
            Account account = accountMapper.selectAccountByUserId(order.getCUserId());
            if (account == null)
            {
                throw new ServiceException("用户账户不存在");
            }

            // 验证积分余额
            BigDecimal requiredPoints = new BigDecimal(payPointAmount).divide(new BigDecimal(100), 2, java.math.RoundingMode.HALF_UP);
            if (account.getPointBalance().compareTo(requiredPoints) < 0)
            {
                throw new ServiceException("积分余额不足");
            }

            // 验证总支付金额
            Long totalPay = payAmount + payPointAmount;
            if (!totalPay.equals(order.getAmount()))
            {
                throw new ServiceException("支付金额不正确");
            }

            // 🚀 优化：使用Redis原子操作扣减库存
            boolean stockDecr = productStockService.decrStock(order.getProductId(), order.getNum());
            if (!stockDecr) {
                throw new ServiceException("商品库存不足");
            }

            // 扣除积分
            if (payPointAmount > 0)
            {
                account.setPointBalance(account.getPointBalance().subtract(requiredPoints));
                
                // 记录积分明细
                Point point = new Point();
                point.setUserId(order.getCUserId());
                point.setType(1); // C端用户
                point.setPoint(requiredPoints);
                point.setIncrease("2"); // 减少
                point.setDeleted(0);
                point.setCreateTime(new Date());
                pointMapper.insertPoint(point);
            }

            // 更新账户
            accountMapper.updateAccount(account);

            // 更新订单状态
            order.setPayAmount(payAmount);
            order.setPayPointAmount(payPointAmount);
            order.setStatue(2); // 已支付
            order.setUpdateTime(new Date());
            orderMapper.updateOrder(order);

            // 🚀 优化：异步同步库存到数据库（后台定时任务会处理）
            // 不需要立即同步，减少数据库写压力

            // 触发分佣计算（如果有人民币支付）
            if (payAmount > 0)
            {
                commissionService.calculateOrderCommission(order);
            }
            
        } catch (Exception e) {
            // 支付失败，恢复库存
            try {
                Order order = orderMapper.selectOrderById(orderId);
                if (order != null && order.getStatue() == 1) {
                    productStockService.incrStock(order.getProductId(), order.getNum());
                }
            } catch (Exception ex) {
                System.err.println("恢复库存失败: " + ex.getMessage());
            }
            throw e;
        } finally {
            // 释放锁
            if (lockValue != null) {
                redisLockUtil.unlock(lockKey, lockValue);
            }
        }
    }

    @Override
    public int updateOrder(Order order)
    {
        order.setUpdateTime(DateUtils.getNowDate());
        return orderMapper.updateOrder(order);
    }

    @Override
    public int deleteOrderById(Long id)
    {
        return orderMapper.deleteOrderById(id);
    }
}

